/**
 * 地图视图组件
 * 用于展示油田、区域、设备和光缆的地理位置信息
 * 支持实时状态更新和交互操作
 */
<template>
    <!-- 地图容器 -->
    <div id="myMap"></div>

</template>

<script setup>
import { onMounted, onUnmounted, defineProps, defineExpose, reactive, watch, ref } from 'vue';
import chargeImg from '@/assets/dataIndex/oil_field.png'
import deviceImg from '@/assets/dataIndex/device_item_0.png'
import deviceImg1 from '@/assets/dataIndex/device_item_1.png'
import deviceImg2 from '@/assets/dataIndex/device_item_2.png'
import deviceImg3 from '@/assets/dataIndex/device_item_3.png'
import deviceImg4 from '@/assets/dataIndex/device_item_4.png'
import deviceImgOff from '@/assets/dataIndex/device_item_off.png'


// 常量定义
const DEFAULT_MAP_CENTER = [112.963057,28.196405]; // 默认地图中心点
const DEFAULT_ZOOM = 13; // 默认缩放级别

// 全局变量声明
let mapExample; // 高德地图实例
let chargeLabelMarkers = []; // 油田标记点数组
let areaLabelMarkers = []; // 区域标记点数组
let chargeLayer; // 油田图层
let timer; // 定时器
let deviceMarkers = []; // 设备标记点数组
let cableLines = []; // 光缆线路数组

// 组件事件定义
const emit = defineEmits(['changeOilField'])

// 组件属性定义
const props = defineProps({
    mapControlData: {
        type: Object,
        default: () => {
            return {
                vehicle: true,
                line: true,
                road: true,
            }
        }
    }
})

// 响应式状态
const state = reactive({
    id: null,
    infoWindowObj: {}, // 信息窗口对象集合
    oilFieldId: '', // 当前选中的油田ID
    deviceList: [], // 设备列表
    alarmData: {}, // 报警数据
})

// 生命周期钩子
onMounted(() => {
    mapInit();
    init();
})

onUnmounted(() => {
    cleanup();
})

// 监听属性变化
watch(() => props.mapControlData, () => {

}, {deep: true})

/**
 * 清理资源
 */
const cleanup = () => {
    mapExample && mapExample.destroy();
    destroyMapWebgl();
    if (timer) {
        clearTimeout(timer);
    }
}

/**
 * 销毁地图WebGL上下文
 */
const destroyMapWebgl = () => {
    document
        .querySelector(`canvas.amap-layer`)
        ?.getContext("webgl")
        ?.getExtension("WEBGL_lose_context")
        ?.loseContext();
};

/**
 * 初始化地图实例
 * 配置地图的基本参数和样式
 */
const mapInit = () => {
    mapExample = new AMap.Map(`myMap`, {
        mapStyle: 'amap://styles/darkblue',
        zoom: DEFAULT_ZOOM,
        zooms: [5, 30],
        center: DEFAULT_MAP_CENTER,
        pitchEnable: false,
        resizeEnable: true,
        doubleClickZoom: true,
        dragEnable: true,
        zoomEnable: true,
        jogEnable: true,
        scrollWheel: true,
        keyboardEnable: true,
        isHotspot: true,
        defaultCursor: "grab",
        features: ["bg", "point", "road", "building"]
    });
}

/**
 * 初始化地图数据和视图
 * 清除现有数据并重新加载
 */
const init = () => {
    mapExample.clearMap();
    clearInfoWindows();
    if (timer) {
        clearTimeout(timer);
    }
    handleAll();
}

/**
 * 清除所有信息窗口
 */
const clearInfoWindows = () => {
    Object.values(state.infoWindowObj).forEach(marker => {
        mapExample.remove(marker);
    });
    state.infoWindowObj = {};
}

/**
 * 刷新地图
 * 重置地图状态并重新初始化
 */
const mapRefresh = () => {
    mapExample && mapExample.destroy();
    chargeLabelMarkers = [];
    chargeLayer = null;
    state.oilFieldId = '';
    clearInfoWindows();
    destroyMapWebgl();
    mapInit();
    init();
}

/**
 * 获取并绘制全量公司-油田数据
 */
const handleAll = () => {
    // queryOrgEquipTree().then(res => {
    //     if (res.status =='000_0000_0000') {
    //         drawChargeStation(res.data[0].oilFieldList);
    //         // 获取项目定位，设置地图中心点
    //         equipOilCompanyEditDetail({id: res.data[0].companyId}).then(r=>{
    //             if(r.success){
    //                 if(mapExample){
    //                     setTimeout(()=>{
    //                         mapExample.setCenter([r.data.longitude,r.data.latitude]);
    //                     }, 500)
    //                 }
    //             }
    //         })
    //     }
    // });
}

/**
 * 绘制油田标记点
 * @param {Array} data - 油田数据列表
 */
const drawChargeStation = (data) => {
    if (!chargeLayer) {
        chargeLayer = new AMap.LabelsLayer({
            zIndex: 50000,
            collision: false,
            animation: false,
        });
        mapExample.add(chargeLayer);
    }

    chargeLayer.remove(chargeLabelMarkers);
    chargeLabelMarkers = [];

    data.forEach((item) => {
        const labelMarker = createChargeLabelMarker(item);
        chargeLabelMarkers.push(labelMarker);
        labelMarker.on("click", handleToChargeDetail);
        drawChargeInfoWindow(item);
    });

    // 调整视图以适应所有标记点
    setTimeout(() => {
        mapExample.setFitView();
        mapExample.setZoom(mapExample.getZoom() - 1);
    }, 100);
    chargeLayer.add(chargeLabelMarkers);
}

/**
 * 创建油田标记点
 * @param {Object} item - 油田数据
 * @returns {AMap.LabelMarker} 标记点对象
 */
const createChargeLabelMarker = (item) => {
    return new AMap.LabelMarker({
        zIndex: 50000,
        position: [item.longitude, item.latitude],
        icon: {
            type: "image",
            image: chargeImg,
            size: [54, 62],
            anchor: "center",
        },
        collision: false,
        allowCollision: false,
        extData: item,
        offset: new AMap.Pixel(-27, -30),
    });
}

/**
 * 处理油田点击事件
 * @param {Object} e - 事件对象
 */
const handleToChargeDetail = (e) => {
    const id = e.target._opts.extData.id || e.target._opts.extData.oilFieldId;
    if (state.oilFieldId && state.oilFieldId === id) return;
    state.oilFieldId = id;
    emit('changeOilField', id);
}

/**
 * 绘制油田信息窗口
 * @param {Object} data - 油田数据
 */
const drawChargeInfoWindow = (data) => {
    const labelContent = createInfoWindowContent(data);
    const labelMarker = new AMap.Marker({
        position: [data.longitude * 1, data.latitude * 1],
        content: labelContent,
        zIndex: 49999,
        offset: data.areaId ? new AMap.Pixel(49, 14) : new AMap.Pixel(102, 14),
        anchor: 'bottom-center',
        extData: data
    });

    if (data.areaId) {
        labelMarker.on('click', showAreaDetail);
    } else {
        labelMarker.on('click', handleToChargeDetail);
    }

    mapExample.add(labelMarker);
    state.infoWindowObj[data.areaId || data.oilFieldId] = labelMarker;
}

/**
 * 创建信息窗口内容
 * @param {Object} data - 数据对象
 * @returns {string} HTML内容
 */
const createInfoWindowContent = (data) => {
    if (data.areaId) {
        return `
            <div class='info_window'>
                <div class='info_window_title'>${data.areaName}</div>
            </div>`;
    }
    return `
        <div class='info_window ${state.oilFieldId ? '' : 'info_window_hover'}'>
            <div class='info_window_title'>${data.oilFieldName || '油田' + data.oilFieldId}</div>
            <div class='info_window_detail'>查看详情</div>
        </div>`;
}

/**
 * 设置油田区域并绘制相关元素
 * @param {Object} data - 油田区域数据
 */
const setOilFieldFence = (data) => {
    clearDeviceAndCables()
    state.oilFieldId = data.id;
    const arr = data.oilFieldFence;
    mapExample.clearMap();
    mapExample.setCenter([data.longitude, data.latitude]);
    mapExample.setZoom(12);

    drawDevice();
    areaLabelMarkers = [];

    arr.forEach(item => {
        drawAreaPolygon(item);
    });

    mapExample.setZoom(mapExample.getZoom() - 1);
}

/**
 * 绘制区域多边形
 * @param {Object} item - 区域数据
 */
const drawAreaPolygon = (item) => {
    const path = item.fenceGpsList.map(r => [r.longitude * 1, r.latitude * 1]);
    const polygon = new AMap.Polygon({
        zIndex: 10000,
        path: path,
        fillColor: '#006EFF',
        fillOpacity: 0.2,
        strokeWeight: 2,
        strokeColor: '#006EFF'
    });

    mapExample.add(polygon);
}

/**
 * 创建区域标记点
 * @param {Object} centerObj - 中心点坐标
 * @param {Object} windowObj - 窗口数据
 * @returns {AMap.LabelMarker} 标记点对象
 */
const createAreaLabelMarker = (centerObj, windowObj) => {
    const labelMarker = new AMap.LabelMarker({
        zIndex: 50000,
        position: [centerObj.lng, centerObj.lat],
        icon: {
            type: "image",
            image: null,
            size: [54, 62],
            anchor: "center",
        },
        collision: false,
        allowCollision: false,
        extData: windowObj,
        offset: new AMap.Pixel(-27, -30),
        rank: 100
    });
    labelMarker.on("click", showAreaDetail);
    return labelMarker;
}

/**
 * 绘制设备标记点和光缆线路
 */
const drawDevice = () => {
    // queryEqCableFenceList({ oilFieldId: state.oilFieldId }).then(res => {
    //     if (res.status =='000_0000_0000') {
    //         clearDeviceAndCables();
    //         res.data.forEach(device => {
    //             drawDeviceMarker(device);
    //             device.cableList.forEach(cable => {
    //                 drawCableLine(cable);
    //             });
    //         });
    //     }
    // });
}

/**
 * 清除设备和光缆
 */
const clearDeviceAndCables = () => {
    deviceMarkers.forEach(marker => {
        mapExample.remove(marker);
    });
    deviceMarkers = [];
    cableLines.forEach(line => {
        mapExample.remove(line);
    });
    cableLines = [];
}

/**
 * 绘制设备标记点
 * @param {Object} device - 设备数据
 */
const drawDeviceMarker = (device) => {
    const deviceMarker = new AMap.LabelMarker({
        zIndex: 50000,
        position: [device.longitude, device.latitude],
        icon: {
            type: "image",
            image: deviceImg,
            size: [80, 40],
            anchor: "center",
        },
        extData: {
            ...device,
            eqId: device.eqId
        },
        offset: new AMap.Pixel(-40, -20),
    });

    deviceMarker.on("click", showDeviceDetail);
    mapExample.add(deviceMarker);
    deviceMarkers.push(deviceMarker);
}

/**
 * 绘制光缆线路
 * @param {Object} cable - 光缆数据
 */
const drawCableLine = (cable) => {
    const line = drawLine(cable.fenceList);
    line.setExtData({
        cableId: cable.cableId
    });
    cableLines.push(line);
}

/**
 * 绘制线路
 * @param {Array} points - 线路点集合
 * @returns {AMap.Polyline} 线路对象
 */
const drawLine = (points) => {
    const path = points.map(point => [point.longitude, point.latitude]);
    const polyline = new AMap.Polyline({
        path: path,
        strokeColor: "#24C38E",
        strokeOpacity: 1,
        strokeWeight: 2
    });
    mapExample.add(polyline);
    return polyline;
}

/**
 * 显示区域详情
 * @param {Object} e - 事件对象
 */
const showAreaDetail = (e) => {
    // areaDetailRef.value.showModal(e.target._opts.extData.areaId);
}

/**
 * 显示设备详情
 * @param {Object} e - 事件对象
 */
const showDeviceDetail = (e) => {
    // DeviceDetailModalRef.value.showModal(e.target._opts.extData.eqId);
}



/**
 * 更新信息窗口内容
 * @param {string} id - 区域或油田ID
 * @param {string} name - 区域或油田名称
 * @param {Object} alarmInfo - 报警信息
 */
const updateInfoWindow = (id, name, alarmInfo) => {
    const infoWindow = state.infoWindowObj[id];
    if (infoWindow) {
        const alarmTags = alarmInfo.alarmLevelList.map(level => {
            const count = level.alarmCt;
            const backgroundColor = getCableColor(level.alarmLevel * 1);
            return `<div class="info_window_tag" style="background: ${backgroundColor};">${count}</div>`;
        }).join('');

        const content = `
            <div class='info_window ${state.oilFieldId ? '' : 'info_window_hover'}'>
                <div class='info_window_title'>${name}</div>
                <div class='info_window_detail'>查看详情</div>
                <div class='info_window_tag_container'>
                    ${alarmTags}
                </div>
            </div>`;
        infoWindow.setContent(content);
    }
}

/**
 * 更新设备和光缆状态
 * @param {Array} eqCableAlarmStatusList - 设备和光缆报警状态列表
 */
const updateDeviceAndCableStatus = (eqCableAlarmStatusList) => {
    if (!eqCableAlarmStatusList||eqCableAlarmStatusList.length===0) return;
    updateDeviceMarkers(eqCableAlarmStatusList);
    updateCableLines(eqCableAlarmStatusList);
}

/**
 * 更新设备标记点状态
 * @param {Array} eqCableAlarmStatusList - 设备报警状态列表
 */
const updateDeviceMarkers = (eqCableAlarmStatusList) => {
    if(deviceMarkers&&deviceMarkers.length>0){
        deviceMarkers.forEach(marker => {
            const deviceInfo = eqCableAlarmStatusList.find(item => item.eqId === marker._opts.extData.eqId);
            if (deviceInfo) {
                marker.setIcon({
                    type: "image",
                    image: getDeviceIcon(deviceInfo),
                    size: [80, 40],
                    anchor: "center",
                });
            }
        });
    }else{
        setTimeout(()=>{
            updateDeviceMarkers(eqCableAlarmStatusList)
        }, 100)
    }
}

/**
 * 更新光缆线路状态
 * @param {Array} eqCableAlarmStatusList - 光缆报警状态列表
 */
const updateCableLines = (eqCableAlarmStatusList) => {
    if(cableLines&&cableLines.length>0){
        cableLines.forEach(line => {
            const deviceInfo = eqCableAlarmStatusList.find(item =>
                item.cableAlarmStatusList.some(cable => cable.cableId === line._opts.extData.cableId)
            );
            if (deviceInfo) {
                const cableInfo = deviceInfo.cableAlarmStatusList.find(
                    cable => cable.cableId === line._opts.extData.cableId
                );
                if (cableInfo) {
                    line.setOptions({
                        strokeColor: getCableColor(cableInfo.cableAlarmStatus)
                    });
                }
            }
        });
    }else{
        setTimeout(()=>{
            updateCableLines(eqCableAlarmStatusList)
        }, 100)
    }

}

/**
 * 获取设备状态对应的图标
 * @param {number} deviceInfo - 设备信息
 * @returns {string} 图标路径
 */
const getDeviceIcon = (deviceInfo) => {
    const iconMap = {
        "off": deviceImgOff,
        0: deviceImg,  // 正常
        1: deviceImg1, // 提示
        2: deviceImg2, // 次要
        3: deviceImg3, // 重要
        4: deviceImg4  // 紧急
    };
    let keyValue = deviceInfo.eqAlarmStatus>0?deviceInfo.eqAlarmStatus:deviceInfo.onLine===0?'off':0
    return iconMap[keyValue] || deviceImg;
}

/**
 * 获取光缆状态对应的颜色
 * @param {number} status - 光缆状态码
 * @returns {string} 颜色代码
 */
const getCableColor = (status) => {
    const colorMap = {
        0: '#24C38E',  // 正常
        1: '#00CCCC',  // 提示报警
        2: '#FF8500',  // 次要报警
        3: '#FF2F00',  // 重要报警
        4: '#AA30D3'   // 紧急报警
    };
    return colorMap[status] || '#24C38E';
}

// 暴露组件方法
defineExpose({

});
</script>

<style lang="less">
#myMap {
    width: 100%;
    height: 100%;
}

.info_window {
    // min-width: 120px;
    width: 150px;
    padding: 6px 0;
    box-sizing: border-box;
    padding-left: 12px;
    background: linear-gradient(90deg, #005F61 0%, rgba(0, 95, 97, 0) 100%);
    display: flex;
    align-items: center;
    position: relative;

    .info_window_title,
    .info_window_detail {
        font-weight: 600;
        font-size: 16px;
        line-height: 16px;
        color: #FFFFFF;
    }

    .info_window_detail {
        display: none;
    }

    .info_window_tag_container {
        position: absolute;
        top: -20px;
        left: 0;
        width: 100%;
        height: 20px;
        box-sizing: border-box;
        padding-left: 12px;
        display: flex;
        align-items: center;
        gap: 2px;
        font-size: 12px;
        color: #FFFFFF;
        font-weight: 600;

        .info_window_tag {
            width: 20px;
            height: 16px;
            // background: #005F61;
            border-radius: 3px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 2px;
            font-size: 12px;
            color: #FFFFFF;
            font-weight: 600;
        }
    }
}

.info_window_hover {
    &:hover {
        .info_window_title {
            display: none;
        }

        .info_window_detail {
            display: block;
        }
    }
}

.amap-logo {
    display: none;
    opacity: 0 !important;
}

.amap-copyright {
    opacity: 0;
}
</style>
